package com.gxa.community.admin.service.mine.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.gxa.community.admin.mapper.OperateTicketMapper;
import com.gxa.community.admin.mapper.agent.UserAgentApplicationMapper;
import com.gxa.community.admin.mapper.mine.UserCouponRelMapper;
import com.gxa.community.admin.mapper.order.OrderInfoMapper;
import com.gxa.community.admin.mapper.order.UserInfoMapper;
import com.gxa.community.admin.service.mine.MineService;
import com.gxa.community.admin.service.order.OrderService;
import com.gxa.community.core.pojo.domain.*;
import com.gxa.community.core.pojo.vo.mine.MineCouponInfoVo;
import com.gxa.community.core.pojo.vo.mine.MinePageInfoVo;
import com.gxa.community.core.utils.R;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;


@Service
public class MineServiceImpl implements MineService {
    final UserCouponRelMapper userCouponRelMapper;
    final OrderInfoMapper orderInfoMapper;
    final UserInfoMapper userInfoMapper;
    final UserAgentApplicationMapper agentMapper;
    final OperateTicketMapper couponMapper;
    final OrderService orderService;

    public MineServiceImpl(UserCouponRelMapper userCouponRelMapper, OrderInfoMapper orderInfoMapper
            , UserInfoMapper userInfoMapper, UserAgentApplicationMapper agentMapper, OperateTicketMapper couponMapper, OrderService orderService) {
        this.userCouponRelMapper = userCouponRelMapper;
        this.orderInfoMapper = orderInfoMapper;
        this.userInfoMapper = userInfoMapper;
        this.agentMapper = agentMapper;
        this.couponMapper = couponMapper;
        this.orderService = orderService;
    }

    @Override
    public R getMineInfo(Integer uid) {
        MinePageInfoVo minePageInfoVo = new MinePageInfoVo();

        // 查询优惠券数量 (未减已过期优惠券
        minePageInfoVo.setCoupon(userCouponRelMapper.selectCount(
                Wrappers.lambdaQuery(UserCouponRel.class)
                        .eq(UserCouponRel::getUserId, uid)
                        .eq(UserCouponRel::getStatus, 1)
        ));

        // 查询待付款订单数量
        minePageInfoVo.setUnpaid(orderInfoMapper.selectCount(
                Wrappers.lambdaQuery(OrderInfo.class)
                        .eq(OrderInfo::getBuyerId, uid)
                        .eq(OrderInfo::getStatus, 1)
        ));

        // 查询待评价订单数量
        minePageInfoVo.setComment(orderInfoMapper.selectCount(
                Wrappers.lambdaQuery(OrderInfo.class)
                        .eq(OrderInfo::getBuyerId, uid)
                        .eq(OrderInfo::getStatus, 3)
        ));

        // 查询团长信息
        UserAgentApplication agentInfo = Optional.ofNullable(
                        // 查询团长ID
                        userInfoMapper.selectOne(
                                Wrappers.lambdaQuery(UserInfo.class)
                                        .eq(UserInfo::getUserId, uid)))
                .map(userInfo -> Optional.ofNullable(userInfo.getAgentId()).map(
                        // 查询团长信息
                        s -> agentMapper.selectOne(
                                Wrappers.lambdaQuery(UserAgentApplication.class)
                                        .eq(UserAgentApplication::getUserId, s)
                        )
                ).orElse(new UserAgentApplication())).orElse(new UserAgentApplication());

        minePageInfoVo.setPointName(agentInfo.getIslandName())
                .setPointAddress(agentInfo.getIslandAddress())
                .setPointCoordinate(agentInfo.getIslandCoordinate());

        return R.ok().put("data", minePageInfoVo);
    }

    @Override
    public R queryCoupon(Integer uid, Integer status) {

        /*
         from  1未使用 2已使用 3已失效
         rel   1未使用(可能已过期) 0已使用
         */

        // 查询优惠券编号
        Set<String> coupons = userCouponRelMapper.selectList(
                Wrappers.lambdaQuery(UserCouponRel.class)
                        .select(UserCouponRel::getCouponNo)
                        .eq(UserCouponRel::getUserId, uid)
                        .eq(UserCouponRel::getStatus, status != null ? (status == 2 ? 0 : 1) : 1)
        ).stream().map(UserCouponRel::getCouponNo).collect(Collectors.toSet());

        // 查询优惠券信息
        List<OperateTicket> operateTickets = couponMapper.selectList(
                Wrappers.lambdaQuery(OperateTicket.class)
                        .in(!coupons.isEmpty(), OperateTicket::getTicketNo, coupons)
                        // 未使用(未过期) 结束时间大于当前时间
                        .gt(status != null && status == 1, OperateTicket::getEndTime, System.currentTimeMillis())
                        // 未使用(已过期) 结束时间小于当前时间
                        .lt(status != null && status == 3, OperateTicket::getEndTime, System.currentTimeMillis())
        );

        List<MineCouponInfoVo> mineCouponInfoVos = new ArrayList<>();
        for (OperateTicket operateTicket : operateTickets)
            mineCouponInfoVos.add(new MineCouponInfoVo()
                    .setName(operateTicket.getName())
                    .setPrice(operateTicket.getPrice())
                    .setFullPrice(operateTicket.getFullPrice())
                    .setUseType(operateTicket.getUseType())
                    .setTicketNo(operateTicket.getTicketNo())
                    .setStartTime(operateTicket.getStartTime())
                    .setEndTime(operateTicket.getEndTime())
            );

        return R.ok().put("data", mineCouponInfoVos);
    }

    @Override
    public R queryGoods(Integer uid, List<String> orderNo) {
        Set<Integer> list = orderInfoMapper.selectList(
                Wrappers.lambdaQuery(OrderInfo.class)
                        .select(OrderInfo::getBuyerId)
                        .in(OrderInfo::getNos, orderNo)
        ).stream().map(OrderInfo::getBuyerId).collect(Collectors.toSet());

        if (list.size() != 1 || list.toArray()[0] != uid) return R.error("订单号有误");
        return orderService.queryGoods(orderNo);
    }
}
